import * as bs from "@/comps/ws/bs";
import { cmds } from "@/comps/ws/cmds";
import { selectRoot, update } from "@/store/rootSlice";
import * as c from "@/util/c";
import { get } from '@/util/http';
import * as tio from "@/util/tio";
import { log } from "@/util/tio";
import TioWebsocket from "@/util/TioWebsocket";
import Cookies from 'js-cookie';
import qs from "query-string";
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";

export let tws;

/**
 * http://localhost:9527/tio-vite-react/?tio_session=8888888888#/demo/PageDemo
 * @param dispatch 
 */
let start = (dispatch) => {
  let metaProvider = async (isReconn) => {
    const { data: resp } = await get(`/im/imserver`);
    const { ok, data, code, msg } = resp
    if (ok) {
      let cookieName = c.SESSION_COOKIE_NAME;
      let urlName = 'tio_session';
      let sid = qs.parse(location.search)[urlName];
      if (!sid) {
        sid = Cookies.get(cookieName);
      }
      tio.replaceUrlQuery({[urlName]:null});

      let params = {
        wx: 1,
        [cookieName]: sid
      }
      return {
        ...data, params
      }
    }
    return null;
  }
  let ping = (tws, ws) => {
    send(cmds.HeartbeatReq)
  }
  tws = new TioWebsocket(metaProvider, { ping, binaryType: 'arraybuffer', reconnInterval: 5000 })
  tws.onopen = (tws, ws, isReconn, event) => {
    update({ twsstate: tws.state() }, dispatch)
    send(cmds.HeartbeatReq)
  }
  tws.onmessage = (tws, ws, data, event) => {
    bs.onmessage(tws, ws, data, event)
  }
  tws.onclose = (tws, ws, event) => {
    log('onclose');
    update({ twsstate: tws.state() }, dispatch)
  }
  tws.ondestroy = (tws) => {
    log('ondestroy');
    update({ twsstate: tws.state() }, dispatch)
  }
  tws.onerror = (tws, ws, event) => {
    log('onerror')
    update({ twsstate: tws.state() }, dispatch)
  }
  tws.connect();
}

/**
 * @param dispatch 
 */
export const init = async (dispatch) => {
  const { data: resp } = await get(`/chat/actChat`, { touid: 23121 });
  start(dispatch)
}
/**
 * demo: 
 * send(cmd.HeartbeatReq, {name:'talent.tan'})
 * send(cmd.HeartbeatReq, null)
 * @param cmdMeta 
 * @param bodyObj 
 */
export const send = (cmdMeta, bodyObj?) => {
  bs.send(tws, cmdMeta, bodyObj);
}


function WsComp({ children, auto = true, ...rest }) {
  const root = useSelector(selectRoot);
  const dispatch = useDispatch();

  useEffect(() => {
    if (auto) {
      init(dispatch)
    }

    return () => {
      if (root.tws) {
        tws.close()
        log('ws closed')
      }
    }
  }, [])

  return (
    <>
      {children}
    </>
  );
}
export default WsComp;
